﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public enum RGBMINMAXCHANNEL_MODE
    {
        MAX,
        MIN
    }

    /// <summary>
    /// Description s. Roborealm
    /// This is used to replace a color with its max or min component.
    /// e.g. MODE MAX: 
    /// RGB is 255, 127, 33 => 255, 0, 0
    ///
    /// MOD MIN:
    /// RGB is 255, 127, 33 => 0, 0, 33
    /// </summary>
    public class RGBMinMaxChannel : BaseImageFilter
    {
        protected int m_nTolerance = 10;
        protected RGBMINMAXCHANNEL_MODE M_MODE = RGBMINMAXCHANNEL_MODE.MAX;

        protected PerPixelFilter m_PerPixelFilterMin = new PerPixelFilter(new PerPixelFilter.PerPixelFilterDelegate(
                            delegate(Color _color)
                            {
                                if (_color.R < _color.G && _color.R < _color.B)
                                {
                                    _color = Color.FromArgb(_color.R, 0, 0);
                                }
                                else if (_color.G < _color.B && _color.G < _color.R)
                                {
                                    _color = Color.FromArgb(0, _color.G, 0);
                                }
                                else if (_color.B < _color.R && _color.B < _color.G)
                                {
                                    _color = Color.FromArgb(0, 0, _color.B);
                                }
                                return _color;
                            }
                        ));

        protected PerPixelFilter m_PerPixelFilterMax =
            new PerPixelFilter(new PerPixelFilter.PerPixelFilterDelegate(
                            delegate(Color _color)
                            {
                                if (_color.R > _color.G && _color.R > _color.B)
                                {
                                    _color = Color.FromArgb(_color.R, 0, 0);
                                }
                                else if (_color.G > _color.B && _color.G > _color.R)
                                {
                                    _color = Color.FromArgb(0, _color.G, 0);
                                }
                                else if (_color.B > _color.R && _color.B > _color.G)
                                {
                                    _color = Color.FromArgb(0, 0, _color.B);
                                }
                                return _color;
                            }
                        )); 

        protected PerPixelFilter m_PerPixelFilter = null;

        /// <summary>
        /// 
        /// </summary>
        public RGBMinMaxChannel()
        {
            MODE = RGBMINMAXCHANNEL_MODE.MAX;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_rgbMinMaxChannel"></param>
        internal RGBMinMaxChannel(RGBMinMaxChannel _rgbMinMaxChannel)
        {
            this.m_nTolerance = _rgbMinMaxChannel.m_nTolerance;
        }

        /// <summary>
        /// Gets or sets perpixelfilter rgb mode
        /// </summary>
        public RGBMINMAXCHANNEL_MODE MODE
        {
            get { return M_MODE; }
            set
            {
                M_MODE = value;
                switch (M_MODE)
                {
                    case RGBMINMAXCHANNEL_MODE.MIN:
                        m_PerPixelFilter = m_PerPixelFilterMin;
                        break;

                    case RGBMINMAXCHANNEL_MODE.MAX:
                        m_PerPixelFilter = m_PerPixelFilterMax;
                        break;
                }
            }
        }

        /// <summary>
        /// Gets or sets tolerance
        /// </summary>
        public int Tolerance
        {
            get { return m_nTolerance; }
            set { m_nTolerance = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            return m_PerPixelFilter.Execute(_bitmap);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new RGBMinMaxChannel(this);
        }
    }
}
